package com.niiwoo.civet.account.service.local.notify;

import java.util.List;
import java.util.stream.Collectors;

import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.account.dao.entity.AccountBase;
import com.niiwoo.civet.account.dao.mapper.AccountBaseMapperExt;
import com.niiwoo.civet.trade.dto.request.GetOpenInvestmentAccountAfterUnInvestment;
import com.niiwoo.civet.trade.dto.response.RecommendInvestResponseDTO;
import com.niiwoo.civet.trade.service.invest.InvestDubboService;
import com.niiwoo.civet.trade.service.notify.PersonalizedNotifyTradeDubboService;
import com.niiwoo.civet.user.dto.request.UserLetterRequestDTO;
import com.niiwoo.civet.user.dto.response.UserBasicInfoResponseDTO;
import com.niiwoo.civet.user.enums.MessageTemplateKeyEnum.JPushTemplateKeyEnum;
import com.niiwoo.civet.user.enums.MessageTemplateKeyEnum.LetterTemplateKeyEnum;
import com.niiwoo.civet.user.enums.SMSTemplateKeyEnum;
import com.niiwoo.civet.user.enums.UserLetterTypeEnum;
import com.niiwoo.civet.user.service.SendSmsDubboService;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.civet.user.service.UserLetterDubboService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class PersonalizedNotifyAccountLocalService {
	
	@Autowired
	private AccountBaseMapperExt accountBaseMapperExt;

	@Reference(version = "1.0.0")
	private UserLetterDubboService userLetterDubboService;
	
	@Reference(version = "1.0.0")
	private SendSmsDubboService sendSmsDubboService;
	
	@Reference(version = "1.0.0")
	private UserBasicInfoDubboService userBasicInfoDubboService;
	
	@Reference(version = "1.0.0")
	private PersonalizedNotifyTradeDubboService personalizedNotifyTradeDubboService;
	
	@Reference(version = "1.0.0")
	private InvestDubboService investDubboService;
	
	/**
	 * 开通投资存管后2天内没有投资
	 */
	public void openInvestmentAccountAfterUnInvestment() {
		Long beginTime = System.currentTimeMillis();
		log.info("###个性化通知-开通投资存管未投资###推送信息任务开始");
		List<AccountBase> accountBaseList = accountBaseMapperExt.selectOpenInvestmentAccountForAssignDays(1);
		if (CollectionUtils.isEmpty(accountBaseList)) {
			log.info("###个性化通知-开通投资存管未投资###当前没有符合条件的存管用户，推送信息任务结束，总耗时：{}ms", System.currentTimeMillis() - beginTime);
			return;
		}
		
		// 汇总用户ID列表
		List<String> userIdListForAccount = accountBaseList.stream().map(AccountBase::getUserId).distinct().collect(Collectors.toList());
		
		// 调用Trade查询没有投资记录的用户
		GetOpenInvestmentAccountAfterUnInvestment requestDTO = new GetOpenInvestmentAccountAfterUnInvestment();
		requestDTO.setUserIdList(userIdListForAccount);
		List<String> userIdList = personalizedNotifyTradeDubboService.getOpenInvestmentAccountAfterUnInvestment(requestDTO);
		if (CollectionUtils.isEmpty(userIdList)) {
			log.info("###个性化通知-开通投资存管未投资###当前没有符合条件的投资订单用户，推送信息任务结束，总耗时：{}ms", System.currentTimeMillis() - beginTime);
			return;
		}
		log.info("###个性化通知-开通投资存管未投资###当前需要推送信息的总用户数：{}", userIdList.size());
		
		// 构建消息参数（所有用户推送的消息参数是一致）
		List<Object> paramMap = Lists.newArrayList();
		log.info("###个性化通知-开通投资存管未投资###信息参数：{}", JSONObject.toJSONString(paramMap));		
		
		// 针对每一个用户推送信息
		userIdList.parallelStream().forEach(userId -> {
			pushOpenInvestmentAccountAfterUnInvestmentMessageToUser(userId, paramMap);
		});
		log.info("###个性化通知-开通投资存管未投资###推送信息任务结束，总耗时：{}ms", System.currentTimeMillis() - beginTime);
	}
	
	/**
	 * 根据用户ID列表获取未开通存管帐户(借款、投资)的用户
	 * 
	 * @param userIdList
	 * @return
	 */
	public List<String> getUnOpenBankAccount(List<String> userIdList) {
		List<String> openBankAccountList = accountBaseMapperExt.selectOpenBankAccoutByUserIdList(userIdList);
		if (!CollectionUtils.isEmpty(openBankAccountList)) {
			userIdList.removeAll(openBankAccountList);
		}
		return userIdList;
	}
	
	/**
	 * 开通投资存管帐户
	 * 
	 * @param userId
	 */
	public void pushOpenInvestmentSuccessMessageToUser(String userId) {
		log.info("###个性化通知-开通投资存管帐户成功###推送信息，UserId:{}", userId);
		try {
			if (!isExistNewProject(userId)) {
				log.info("###个性化通知-开通投资存管帐户成功###当前没有符合条件的推荐新手标，推送信息结束，UserId:{}", userId);
				return;
			}
			
			UserBasicInfoResponseDTO responseDTO = userBasicInfoDubboService.getUserBasicInfo(userId);
			
			// 内容参数
			List<Object> paramMap = Lists.newArrayList();
			
			// 站内信和极光推送
			UserLetterRequestDTO userLetterRequestDTO = new UserLetterRequestDTO();
			userLetterRequestDTO.setToUserId(responseDTO.getUserId());
			userLetterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
			userLetterRequestDTO.setJpushTemplateKeyEnum(JPushTemplateKeyEnum.PERSONALIZED_NOTIFY_OPEN_INVEST_ACCOUNT_SUCCESS);
			userLetterRequestDTO.setJpushTemplateParamList(paramMap);
			userLetterRequestDTO.setLetterTemplateEnum(LetterTemplateKeyEnum.PERSONALIZED_NOTIFY_OPEN_INVEST_ACCOUNT_SUCCESS);
			userLetterRequestDTO.setLetterTemplateParamList(paramMap);
			userLetterDubboService.pushLetter(userLetterRequestDTO);
			
			// 发送短信
			sendSmsDubboService.sendSmsByMobile(responseDTO.getMobileNo(),
					SMSTemplateKeyEnum.PERSONALIZED_NOTIFY_OPEN_INVEST_ACCOUNT_SUCCESS.getKey(), paramMap);
		} catch (Exception e) {
			log.error("###个性化通知-开通投资存管帐户成功###推送信息异常，UserId:{}", userId, e);
		}
		log.info("###个性化通知-开通投资存管帐户成功###推送信息结束，UserId:{}", userId);
	}
	
	/**
	 * 个性化通知-开通投资存管未投资
	 * 
	 * @param userId
	 * @param paramMap
	 */
	private void pushOpenInvestmentAccountAfterUnInvestmentMessageToUser(String userId, List<Object> paramMap) {
		log.info("###个性化通知-开通投资存管未投资###推送信息，UserId:{}", userId);
		try {
			if (!isExistNewProject(userId)) {
				log.info("###个性化通知-开通投资存管未投资###当前没有符合条件的推荐新手标，推送信息结束，UserId:{}", userId);
				return;
			}
			
			UserBasicInfoResponseDTO responseDTO = userBasicInfoDubboService.getUserBasicInfo(userId);
			
			// 站内信和极光推送
			UserLetterRequestDTO userLetterRequestDTO = new UserLetterRequestDTO();
			userLetterRequestDTO.setToUserId(responseDTO.getUserId());
			userLetterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
			userLetterRequestDTO.setJpushTemplateKeyEnum(JPushTemplateKeyEnum.PERSONALIZED_NOTIFY_NO_INVEST);
			userLetterRequestDTO.setJpushTemplateParamList(paramMap);
			userLetterRequestDTO.setLetterTemplateEnum(LetterTemplateKeyEnum.PERSONALIZED_NOTIFY_NO_INVEST);
			userLetterRequestDTO.setLetterTemplateParamList(paramMap);
			userLetterDubboService.pushLetter(userLetterRequestDTO);
			
			// 发送短信
			sendSmsDubboService.sendSmsByMobile(responseDTO.getMobileNo(),
					SMSTemplateKeyEnum.PERSONALIZED_NOTIFY_NO_INVESTMENT.getKey(), paramMap);
		} catch (Exception e) {
			log.error("###个性化通知-开通投资存管未投资###推送信息异常，UserId:{}", userId, e);
		}
		log.info("###个性化通知-开通投资存管未投资###推送信息结束，UserId:{}", userId);
	}
	
	/**
	 * 是否存在新手标
	 * 
	 * @param userId
	 * @return
	 */
	private Boolean isExistNewProject(String userId) {
		try {
			RecommendInvestResponseDTO responseDTO = investDubboService.queryNoviceRecommendInvest(userId);
			if (null != responseDTO && Byte.valueOf("1").equals(responseDTO.getIsNewProject())) {
				return true;
			}
		} catch (Exception e) {
			log.error("###个性化通知-新手加息特权使用提醒###调用交易中心查询是否有新手标异常，UserId:{}", userId, e);
		}
		return false;
	}
}